﻿using System;
using System.Data.Common;

using Centido.Core;

namespace Centido.Management.ConsoleManager
{
    /// <summary>
    ///   Uninstalls LoBDb.NET metadata.
    /// </summary>
    internal class UninstallCommand : PreLoginCommandBase
    {
        /// <summary>
        ///   Gets the console command name.
        /// </summary>
        public override string Name
        {
            get { return "uninstall"; }
        }


        /// <summary>
        ///   Gets the console command description.
        /// </summary>
        public override string Description
        {
            get { return Messages.UninstallCommandDescription; }
        }


        /// <summary>
        ///   Gets the console command full description.
        /// </summary>
        public override string FullDescription
        {
            get { return Messages.UninstallCommandFullDescription; }
        }


        /// <summary>
        ///   Checks the console command parameters.
        /// </summary>
        /// <param name="context">The console command execution context.</param>
        /// <returns>Returns true if everything is ok; otherwise, returns false.</returns>
        protected override bool CheckCommandParameters(CommandExecutionContext context)
        {
            var result = base.CheckCommandParameters(context);

            if (!result)
                Console.WriteLine(Messages.UninstallCommandNotAllParametersSpecifiedMessage);

            return result;
        }


        /// <summary>
        ///   Executes the console command.
        /// </summary>
        /// <param name="context">The console command execution context.</param>
        /// <exception cref="ArgumentNullException">Thrown when the value of <paramref name="context"/> is null.</exception>
        public override void Execute(CommandExecutionContext context)
        {
            base.Execute(context);

            if (!CheckCommandParameters(context)) return;

            // Getting the provider name
            var providerName = context.GetParameterValue(ProviderNameParameter);

            // Searching for a connection builder
            var connStrBuilder = ConnectionStringBuilders.GetBuilder(providerName);

            if (connStrBuilder == null)
            {
                Console.WriteLine(Messages.NoConnectionBuilderError);
                return;
            }

            // Searching for an installer
            var installer = Installers.GetInstaller(connStrBuilder.ProductName);

            if (installer == null)
            {
                Console.WriteLine(Messages.NoInstallerError);
                return;
            }
            
            // Building a connection string for installing application user
            var connectionString = PopulateConnectionString(context);

            if (string.IsNullOrEmpty(connectionString)) return;

            installer.DbConnectionString = connectionString;

            installer.DbProviderName = providerName;

            try
            {
                // Unistalling the metadata
                installer.Uninstall();
            }
            catch (ArgumentException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();

                return;
            }
            catch (DbException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();

                // Displaying the connection string
                Console.WriteLine(Messages.UsedConnectionStringHint,
                    installer.DbConnectionString);
                return;
            }

            // Displaying the success message
            Console.WriteLine(Messages.CommandCompletedMessage);
        }
    }
}
